/* 
 * Copyright (C) 2007 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.android.notepad;

import com.google.provider.NotePad;

import android.app.ListActivity;
import android.content.ComponentName;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.drawable.Drawable;
import android.net.ContentURI;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.View;
import android.view.View.MeasureSpec;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.TextView;


/**
 * Displays a list of notes. Will display notes from the ContentUri
 * provided int the intent if there is one, otherwise uses the default list
 * from the 
 *
 */
public class NotesList extends ListActivity {
    
    // Menu item Ids
    public static final int DELETE_ID = Menu.FIRST;
    public static final int INSERT_ID = Menu.FIRST + 1;

    /**
     * The columns we are interested in from the database
     */
    private static final String[] PROJECTION = new String[] {
            NotePad.Notes._ID, NotePad.Notes.TITLE};
    
    /**
     * Cursor which holds list of all notes
     */
    private Cursor mCursor;


    @Override
    protected void onCreate(Bundle icicle) {
        super.onCreate(icicle);

        setDefaultKeyMode(SHORTCUT_DEFAULT_KEYS);

        // If no data was given in the intent (because we were started
        // as a MAIN activity), then use our default content provider.
        Intent intent = getIntent();
        if (intent.getData() == null) {
            intent.setData(NotePad.Notes.CONTENT_URI);
        }
        
        setupListStripes();

        mCursor = managedQuery(getIntent().getData(), PROJECTION, null, null);
        
        // Used to map notes entries from the database to views
        ListAdapter adapter = new SimpleCursorAdapter(this,
                android.R.layout.simple_list_item_1, mCursor,
                new String[] {NotePad.Notes.TITLE}, new int[] {android.R.id.text1});
        setListAdapter(adapter);
    }

    /**
     * Add stripes to the list view.
     */
    private void setupListStripes() {
        // Get Drawables for alternating stripes
        Drawable[] lineBackgrounds = new Drawable[2];
        
        lineBackgrounds[0] = getResources().getDrawable(R.drawable.even_stripe);
        lineBackgrounds[1] = getResources().getDrawable(R.drawable.odd_stripe);

        // Make and measure a sample TextView of the sort our adapter will
        // return
        View view = getViewInflate().inflate(
                android.R.layout.simple_list_item_1, null, null);

        TextView v = (TextView) view.findViewById(android.R.id.text1);
        v.setText("X");
        // Make it 100 pixels wide, and let it choose its own height.
        v.measure(MeasureSpec.makeMeasureSpec(View.MeasureSpec.EXACTLY, 100),
                MeasureSpec.makeMeasureSpec(View.MeasureSpec.UNSPECIFIED, 0));
        int height = v.getMeasuredHeight();
        getListView().setStripes(lineBackgrounds, height);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);

        // This is our one standard application action -- inserting a
        // new note into the list.
        menu.add(0, INSERT_ID, R.string.menu_insert).setShortcut(
                KeyEvent.KEYCODE_3, 0, KeyEvent.KEYCODE_A);

        // Generate any additional actions that can be performed on the
        // overall list.  In a normal install, there are no additional
        // actions found here, but this allows other applications to extend
        // our menu with their own actions.
        Intent intent = new Intent(null, getIntent().getData());
        intent.addCategory(Intent.ALTERNATIVE_CATEGORY);
        menu.addIntentOptions(
            Menu.ALTERNATIVE, 0, new ComponentName(this, NotesList.class),
            null, intent, 0, null);

        return true;
    }

    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        super.onPrepareOptionsMenu(menu);
        final boolean haveItems = mCursor.count() > 0;

        // If there are any notes in the list (which implies that one of
        // them is selected), then we need to generate the actions that
        // can be performed on the current selection.  This will be a combination
        // of our own specific actions along with any extensions that can be
        // found.
        if (haveItems) {
            // This is the selected item.
            ContentURI uri = getIntent().getData().addId(getSelectionRowID());

            // Build menu...  always starts with the EDIT action...
            Intent[] specifics = new Intent[1];
            specifics[0] = new Intent(Intent.EDIT_ACTION, uri);
            Menu.Item[] items = new Menu.Item[1];

            // ... is followed by whatever other actions are available...
            Intent intent = new Intent(null, uri);
            intent.addCategory(Intent.SELECTED_ALTERNATIVE_CATEGORY);
            menu.addIntentOptions(Menu.SELECTED_ALTERNATIVE, 0, null, specifics,
                                  intent, Menu.NO_SEPARATOR_AFTER, items);

            // ... and ends with the delete command.
            menu.add(Menu.SELECTED_ALTERNATIVE, DELETE_ID, R.string.menu_delete).
                setShortcut(KeyEvent.KEYCODE_2, 0, KeyEvent.KEYCODE_D);
            menu.addSeparator(Menu.SELECTED_ALTERNATIVE, 0);

            // Give a shortcut to the edit action.
            if (items[0] != null) {
                items[0].setShortcut(KeyEvent.KEYCODE_1, 0, KeyEvent.KEYCODE_E);
            }
        } else {
            menu.removeGroup(Menu.SELECTED_ALTERNATIVE);
        }

        // Make sure the delete action is disabled if there are no items.
        menu.setItemShown(DELETE_ID, haveItems);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(Menu.Item item) {
        switch (item.getId()) {
        case DELETE_ID:
            deleteItem();
            return true;
        case INSERT_ID:
            insertItem();
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    @Override
    protected void onListItemClick(ListView l, View v, int position, long id) {
        ContentURI url = getIntent().getData().addId(getSelectionRowID());
        
        String action = getIntent().getAction();
        if (Intent.PICK_ACTION.equals(action)
                || Intent.GET_CONTENT_ACTION.equals(action)) {
            // The caller is waiting for us to return a note selected by
            // the user.  The have clicked on one, so return it now.
            setResult(RESULT_OK, url.toString());
        } else {
            // Launch activity to view/edit the currently selected item
            startActivity(new Intent(Intent.EDIT_ACTION, url));
        }
    }

    private final void deleteItem() {
        mCursor.moveTo(getSelection());
        mCursor.deleteRow();
    }

    private final void insertItem() {
        // Launch activity to insert a new item
        startActivity(new Intent(Intent.INSERT_ACTION, getIntent().getData()));
    }
}

